<template>
  <PageWrapper title="表格拖拽实例">
    <ATable
      class="table-drag"
      :columns="columns"
      :dataSource="dataSource"
      :rowKey="(record) => record.id"
      :customRow="isSort ? customRow : undefined"
      :pagination="false"
      :size="'middle'"
    >
      <template #bodyCell="data">
        <HolderOutlined v-if="(data.column as any).slot === 'sort'" />
      </template>
    </ATable>
  </PageWrapper>
</template>
<script lang="ts" setup>
  import { onMounted, ref } from 'vue';
  import { Table } from 'ant-design-vue';
  import { HolderOutlined } from '@ant-design/icons-vue';
  import { addClass, removeClass } from '/@/utils/domUtils';
  import { PageWrapper } from '/@/components/Page';
  import { postListData } from '/@/api/sys/post';
  import { AdditionalProps } from 'ant-design-vue/es/vc-table/interface';

  const ATable = Table;
  function t(s) {
    return s;
  }

  const columns: any = [
    {
      title: '#',
      dataIndex: 'sort',
      width: 30,
      align: 'center',
      slot: 'sort',
    },
    {
      title: t('岗位名称'),
      dataIndex: 'postName',
      width: 130,
      align: 'center',
    },
    {
      title: t('岗位代码'),
      dataIndex: 'viewCode',
      width: 130,
      align: 'center',
    },
    {
      title: t('岗位分类'),
      dataIndex: 'postType',
      width: 130,
      align: 'center',
      dictType: 'sys_post_type',
    },
    {
      title: t('排序'),
      dataIndex: 'postSort',
      width: 100,
      align: 'center',
    },
    {
      title: t('状态'),
      dataIndex: 'status',
      width: 100,
      align: 'center',
      dictType: 'sys_status',
    },
    {
      title: t('更新时间'),
      dataIndex: 'updateDate',
      width: 130,
      align: 'center',
    },
    {
      title: t('备注信息'),
      dataIndex: 'remarks',
      width: 130,
      align: 'left',
    },
  ];

  const sourceIdx = ref(0);
  const sourceObj = ref<Recordable>({});
  const targetObj = ref<Recordable>({});
  const dataSource = ref<any>([]);

  onMounted(async () => {
    const res = await postListData();
    dataSource.value = res.list;
  });

  const isSort = ref(true);
  const removeStyle = () => {
    const tbody = document.getElementsByClassName('ant-table-tbody');
    for (const tb of tbody as any) {
      const trs = tb.getElementsByTagName('tr');
      for (const tr of trs) {
        removeClass(tr, 'dragover-top dragover-bottom');
      }
    }
  };

  const customRow = (record: any, index: any): AdditionalProps => {
    return {
      style: {
        cursor: 'grab',
      },
      onMouseenter: (event: any) => {
        const ev = event || window.event;
        ev.target.draggable = true;
      },
      onDragstart: (event: any) => {
        const ev = event || window.event;
        ev.stopPropagation();
        sourceIdx.value = index;
        sourceObj.value = record;
      },
      onDragover: (event: any) => {
        const ev = event || window.event;
        ev.preventDefault();
        const tbodys = document.getElementsByClassName('ant-table-tbody');
        for (const tbody of tbodys as any) {
          let i = 0;
          const trs = tbody.getElementsByTagName('tr');
          for (const tr of trs) {
            if (i++ === index) {
              addClass(tr, 'dragover-' + (sourceIdx.value > index ? 'top' : 'bottom'));
            } else {
              removeClass(tr, 'dragover-top dragover-bottom');
            }
          }
        }
      },
      onDrop: (event: any) => {
        const ev = event || window.event;
        ev.stopPropagation();
        targetObj.value = record;

        const newArr = dataSource.value;
        const source = newArr.findIndex((item) => item.id == sourceObj.value.id);
        const target = newArr.findIndex((item) => item.id == targetObj.value.id);

        newArr.splice(source, 1);
        newArr.splice(target, 0, sourceObj.value);
        console.log(newArr);

        removeStyle();
      },
      onMouseleave: (event: any) => {
        const ev = event || window.event;
        ev.target.draggable = false;
        removeStyle();
      },
    };
  };
</script>
<style lang="less">
  .ant-table-wrapper.table-drag {
    tr.dragover {
      &-top td {
        border-top: 2px solid rgb(22 119 255 / 30%) !important;
        border-top-left-radius: 0 !important;
        border-top-right-radius: 0 !important;
      }

      &-bottom td {
        border-bottom: 2px solid rgb(22 119 255 / 30%) !important;
        border-bottom-left-radius: 0 !important;
        border-bottom-right-radius: 0 !important;
      }
    }
  }
</style>
